package com.bestvike.portal.service.impl;

import com.bestvike.commons.crypto.bcrypt.BCryptPasswordEncoder;
import com.bestvike.commons.exception.ServiceException;
import com.bestvike.commons.support.ExampleCriteria;
import com.bestvike.commons.utils.EncryptUtils;
import com.bestvike.commons.utils.MybatisUtils;
import com.bestvike.commons.utils.StringUtils;
import com.bestvike.portal.dao.SysRoleDao;
import com.bestvike.portal.dao.SysUserDao;
import com.bestvike.portal.data.SysRole;
import com.bestvike.portal.data.SysUser;
import com.bestvike.portal.enums.UserStatus;
import com.bestvike.portal.service.BaseService;
import com.bestvike.portal.service.SysUserService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.security.NoSuchAlgorithmException;
import java.util.*;

@Service
public class SysUserServiceImpl extends BaseService implements SysUserService {
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysRoleDao sysRoleDao;

    @Value("${app.authority.default-password:666666}")
    private String defaultPassword;

    @Override
    public PageInfo<SysUser> fetch(SysUser sysUser) {
        return MybatisUtils.page(sysUser, sysUserDao, new ExampleCriteria() {
            @Override
            public void initCriteria(Example.Criteria criteria) {
                /*if (!StringUtils.isEmpty(sysUser.getDeptId())) {
                    criteria.andEqualTo("deptId", sysUser.getDeptId());
                }*/
                if (!StringUtils.isEmpty(sysUser.getDeptId())) {
                    criteria.andEqualTo("deptId", sysUser.getDeptId());
                }
                criteria.andEqualTo("status", UserStatus.NORMAL.getCode());
                if (!StringUtils.isEmpty(sysUser.getFuzzy())) {
                    criteria.andLike("id", "%" + sysUser.getFuzzy() + "%");
                    criteria.orLike("userId", "%" + sysUser.getFuzzy() + "%");
                    //criteria.orLike("avatar", "%" + fuzzy + "%");
                    criteria.orLike("name", "%" + sysUser.getFuzzy() + "%");
                } else {
                    if (!StringUtils.isEmpty(sysUser.getId())) {
                        criteria.andEqualTo("id", sysUser.getId());
                    }
                    if (!StringUtils.isEmpty(sysUser.getUserId())) {
                        criteria.andEqualTo("userId", sysUser.getUserId());
                    }
                    if (!StringUtils.isEmpty(sysUser.getName())) {
                        criteria.andLike("name", "%" + sysUser.getName() + "%");
                    }
                    if (!StringUtils.isEmpty(sysUser.getStatus())) {
                        criteria.andEqualTo("status", sysUser.getStatus());
                    }
                }
            }
        });
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int modifyAvatar(String id, String avatar) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setAvatar(avatar);
        return sysUserDao.updateByPrimaryKeySelective(sysUser);
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int modifySettings(String id, Map<String, Object> settings) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setSettingsMap(settings);
        return sysUserDao.updateByPrimaryKeySelective(sysUser);
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int create(SysUser sysUser) throws NoSuchAlgorithmException {
        if (!StringUtils.isEmpty(sysUser.getUserId())) {
            Example example = new Example(SysUser.class);
            example.createCriteria().andEqualTo("userId", sysUser.getUserId());
            int cnt = sysUserDao.selectCountByExample(example);
            if (cnt > 0) {
                throw new ServiceException("该用户编号已存在");
            }
        }
        if (StringUtils.isEmpty(sysUser.getPassword())) {
            sysUser.setPassword(new BCryptPasswordEncoder().encode(EncryptUtils.MD5Encode(defaultPassword)));
        }
        if (StringUtils.isEmpty(sysUser.getId())) {
            sysUser.setId(StringUtils.guid());
        }
        if (StringUtils.isEmpty(sysUser.getStatus())) {
            sysUser.setStatus(UserStatus.NORMAL.getCode());
        }
        return sysUserDao.insert(sysUser);
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int modify(SysUser sysUser) {
        Example example = new Example(SysUser.class);
        example.createCriteria().andEqualTo("userId", sysUser.getUserId());
        SysUser temp = sysUserDao.selectOneByExample(example);
        if (temp != null && !temp.getId().equals(sysUser.getId())) {
            throw new ServiceException("该用户编号已存在");
        }
        return sysUserDao.updateByPrimaryKeySelective(sysUser);
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int modifyDepartment(SysUser sysUser) {
        Example example = new Example(SysUser.class);
        example.createCriteria().andIn("id", sysUser.getIds());
        return sysUserDao.updateByExampleSelective(sysUser, example);
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int remove(String ids) {
        SysUser sysUser = new SysUser();
        sysUser.setStatus(UserStatus.DELETED.getCode());
        Example example = new Example(SysUser.class);
        example.createCriteria().andIn("id", Arrays.asList(ids.split(",")));
        return sysUserDao.updateByExampleSelective(sysUser, example);
    }

    @Override
    public int resetPass(String id) {
        try {
            String password = new BCryptPasswordEncoder().encode(EncryptUtils.MD5Encode(defaultPassword));
            return sysUserDao.resetPassword(id, password);
        } catch (NoSuchAlgorithmException e) {
            throw new ServiceException("密码加密异常");
        }
    }

    @Override
    public Map<String, List<SysRole>> fetchGrants(String id) {
        Map<String, List<SysRole>> map = new HashMap<>();
        List<SysRole> roles = sysRoleDao.selectAll();
        List<SysRole> grants = new ArrayList<>();
        SysUser sysUser = sysUserDao.selectByPrimaryKey(id);
        if (!StringUtils.isEmpty(sysUser.getRoles())) {
            String[] userRoles = sysUser.getRoles().split(",");
            for (String userRole : userRoles) {
                SysRole sysRole = sysRoleDao.selectByPrimaryKey(userRole);
                if (sysRole != null) {
                    grants.add(sysRole);
                }
            }
        }
        map.put("roles", roles);
        map.put("grants", grants);
        return map;
    }

    @Override
    public int saveGrants(String id, String[] roles) {
        String roleIds = "";
        if (roles != null && roles.length > 0) {
            roleIds = String.join(",", roles);
        }
        return sysUserDao.saveGrants(id, roleIds);
    }
}
